home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / gdb-4.12 / gdb / inflow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  18.0 KB  |  677 lines

  1. /* Low level interface to ptrace, for GDB when running under Unix.
  2.    Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "frame.h"
  22. #include "inferior.h"
  23. #include "command.h"
  24. #include "signals.h"
  25. #include "serial.h"
  26. #include "terminal.h"
  27. #include "target.h"
  28. #include "thread.h"
  29.  
  30. #include <signal.h>
  31. #include <fcntl.h>
  32.  
  33. #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY) && !defined (__GO32__)
  34. #define HAVE_SGTTY
  35. #endif
  36.  
  37. #if defined (HAVE_TERMIOS)
  38. #include <termios.h>
  39. #include <unistd.h>
  40. #endif
  41.  
  42. #ifdef HAVE_TERMIOS
  43. #define PROCESS_GROUP_TYPE pid_t
  44. #endif
  45.  
  46. #ifdef HAVE_SGTTY
  47. #ifdef SHORT_PGRP
  48. /* This is only used for the ultra.  Does it have pid_t?  */
  49. #define PROCESS_GROUP_TYPE short
  50. #else
  51. #define PROCESS_GROUP_TYPE int
  52. #endif
  53. #endif /* sgtty */
  54.  
  55. static void
  56. kill_command PARAMS ((char *, int));
  57.  
  58. static void
  59. terminal_ours_1 PARAMS ((int));
  60.  
  61. /* Nonzero if we are debugging an attached outside process
  62.    rather than an inferior.  */
  63.  
  64. int attach_flag;
  65.  
  66.  
  67. /* Record terminal status separately for debugger and inferior.  */
  68.  
  69. static serial_t stdin_serial;
  70.  
  71. /* TTY state for the inferior.  We save it whenever the inferior stops, and
  72.    restore it when it resumes.  */
  73. static serial_ttystate inferior_ttystate;
  74.  
  75. /* Our own tty state, which we restore every time we need to deal with the
  76.    terminal.  We only set it once, when GDB first starts.  The settings of
  77.    flags which readline saves and restores and unimportant.  */
  78. static serial_ttystate our_ttystate;
  79.  
  80. /* fcntl flags for us and the inferior.  Saved and restored just like
  81.    {our,inferior}_ttystate.  */
  82. static int tflags_inferior;
  83. static int tflags_ours;
  84.  
  85. #ifdef PROCESS_GROUP_TYPE
  86. /* Process group for us and the inferior.  Saved and restored just like
  87.    {our,inferior}_ttystate.  */
  88. PROCESS_GROUP_TYPE our_process_group;
  89. PROCESS_GROUP_TYPE inferior_process_group;
  90. #endif
  91.  
  92. /* While the inferior is running, we want SIGINT and SIGQUIT to go to the
  93.    inferior only.  If we have job control, that takes care of it.  If not,
  94.    we save our handlers in these two variables and set SIGINT and SIGQUIT
  95.    to SIG_IGN.  */
  96. static void (*sigint_ours) ();
  97. static void (*sigquit_ours) ();
  98.  
  99. /* The name of the tty (from the `tty' command) that we gave to the inferior
  100.    when it was last started.  */
  101.  
  102. static char *inferior_thisrun_terminal;
  103.  
  104. /* Nonzero if our terminal settings are in effect.  Zero if the
  105.    inferior's settings are in effect.  Ignored if !gdb_has_a_terminal
  106.    ().  */
  107.  
  108. static int terminal_is_ours;
  109.  
  110. enum {yes, no, have_not_checked} gdb_has_a_terminal_flag = have_not_checked;
  111.  
  112. /* Does GDB have a terminal (on stdin)?  */
  113. int
  114. gdb_has_a_terminal ()
  115. {
  116.   switch (gdb_has_a_terminal_flag)
  117.     {
  118.     case yes:
  119.       return 1;
  120.     case no:
  121.       return 0;
  122.     case have_not_checked:
  123.       /* Get all the current tty settings (including whether we have a tty at
  124.      all!).  Can't do this in _initialize_inflow because SERIAL_FDOPEN
  125.      won't work until the serial_ops_list is initialized.  */
  126.  
  127. #ifdef F_GETFL
  128.       tflags_ours = fcntl (0, F_GETFL, 0);
  129. #endif
  130.  
  131.       gdb_has_a_terminal_flag = no;
  132.       stdin_serial = SERIAL_FDOPEN (0);
  133.       if (stdin_serial != NULL)
  134.     {
  135.       our_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
  136.  
  137.       if (our_ttystate != NULL)
  138.         {
  139.           gdb_has_a_terminal_flag = yes;
  140. #ifdef HAVE_TERMIOS
  141.           our_process_group = tcgetpgrp (0);
  142. #endif
  143. #ifdef HAVE_SGTTY
  144.           ioctl (0, TIOCGPGRP, &our_process_group);
  145. #endif
  146.         }
  147.     }
  148.  
  149.       return gdb_has_a_terminal_flag == yes;
  150.     default:
  151.       /* "Can't happen".  */
  152.       return 0;
  153.     }
  154. }
  155.  
  156. /* Macro for printing errors from ioctl operations */
  157.  
  158. #define    OOPSY(what)    \
  159.   if (result == -1)    \
  160.     fprintf_unfiltered(gdb_stderr, "[%s failed in terminal_inferior: %s]\n", \
  161.         what, strerror (errno))
  162.  
  163. static void terminal_ours_1 PARAMS ((int));
  164.  
  165. /* Initialize the terminal settings we record for the inferior,
  166.    before we actually run the inferior.  */
  167.  
  168. void
  169. terminal_init_inferior ()
  170. {
  171.   if (gdb_has_a_terminal ())
  172.     {
  173.       /* We could just as well copy our_ttystate (if we felt like adding
  174.      a new function SERIAL_COPY_TTY_STATE).  */
  175.       if (inferior_ttystate)
  176.     free (inferior_ttystate);
  177.       inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
  178. #ifdef PROCESS_GROUP_TYPE
  179. #ifdef PIDGET
  180.       /* This is for Lynx, and should be cleaned up by having Lynx be
  181.      a separate debugging target with a version of
  182.      target_terminal_init_inferior which passes in the process
  183.      group to a generic routine which does all the work (and the
  184.      non-threaded child_terminal_init_inferior can just pass in
  185.      inferior_pid to the same routine).  */
  186.       inferior_process_group = PIDGET (inferior_pid);
  187. #else
  188.       inferior_process_group = inferior_pid;
  189. #endif
  190. #endif
  191.  
  192.       /* Make sure that next time we call terminal_inferior (which will be
  193.      before the program runs, as it needs to be), we install the new
  194.      process group.  */
  195.       terminal_is_ours = 1;
  196.     }
  197. }
  198.  
  199. /* Put the inferior's terminal settings into effect.
  200.    This is preparation for starting or resuming the inferior.  */
  201.  
  202. void
  203. terminal_inferior ()
  204. {
  205.   if (gdb_has_a_terminal () && terminal_is_ours
  206.       && inferior_thisrun_terminal == 0)
  207.     {
  208.       int result;
  209.  
  210. #ifdef F_GETFL
  211.       /* Is there a reason this is being done twice?  It happens both
  212.      places we use F_SETFL, so I'm inclined to think perhaps there
  213.      is some reason, however perverse.  Perhaps not though...  */
  214.       result = fcntl (0, F_SETFL, tflags_inferior);
  215.       result = fcntl (0, F_SETFL, tflags_inferior);
  216.       OOPSY ("fcntl F_SETFL");
  217. #endif
  218.  
  219.       /* Because we were careful to not change in or out of raw mode in
  220.      terminal_ours, we will not change in our out of raw mode with
  221.      this call, so we don't flush any input.  */
  222.       result = SERIAL_SET_TTY_STATE (stdin_serial, inferior_ttystate);
  223.       OOPSY ("setting tty state");
  224.  
  225.       if (!job_control)
  226.     {
  227.       sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN);
  228.       sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN);
  229.     }
  230.  
  231.       /* If attach_flag is set, we don't know whether we are sharing a
  232.      terminal with the inferior or not.  (attaching a process
  233.      without a terminal is one case where we do not; attaching a
  234.      process which we ran from the same shell as GDB via `&' is
  235.      one case where we do, I think (but perhaps this is not
  236.      `sharing' in the sense that we need to save and restore tty
  237.      state)).  I don't know if there is any way to tell whether we
  238.      are sharing a terminal.  So what we do is to go through all
  239.      the saving and restoring of the tty state, but ignore errors
  240.      setting the process group, which will happen if we are not
  241.      sharing a terminal).  */
  242.  
  243.       if (job_control)
  244.     {
  245. #ifdef HAVE_TERMIOS
  246.       result = tcsetpgrp (0, inferior_process_group);
  247.       if (!attach_flag)
  248.         OOPSY ("tcsetpgrp");
  249. #endif
  250.  
  251. #ifdef HAVE_SGTTY
  252.       result = ioctl (0, TIOCSPGRP, &inferior_process_group);
  253.       if (!attach_flag)
  254.         OOPSY ("TIOCSPGRP");
  255. #endif
  256.     }
  257.  
  258.     }
  259.   terminal_is_ours = 0;
  260. }
  261.  
  262. /* Put some of our terminal settings into effect,
  263.    enough to get proper results from our output,
  264.    but do not change into or out of RAW mode
  265.    so that no input is discarded.
  266.  
  267.    After doing this, either terminal_ours or terminal_inferior
  268.    should be called to get back to a normal state of affairs.  */
  269.  
  270. void
  271. terminal_ours_for_output ()
  272. {
  273.   terminal_ours_1 (1);
  274. }
  275.  
  276. /* Put our terminal settings into effect.
  277.    First record the inferior's terminal settings
  278.    so they can be restored properly later.  */
  279.  
  280. void
  281. terminal_ours ()
  282. {
  283.   terminal_ours_1 (0);
  284. }
  285.  
  286. /* output_only is not used, and should not be used unless we introduce
  287.    separate terminal_is_ours and terminal_is_ours_for_output
  288.    flags.  */
  289.  
  290. static void
  291. terminal_ours_1 (output_only)
  292.      int output_only;
  293. {
  294.   /* Checking inferior_thisrun_terminal is necessary so that
  295.      if GDB is running in the background, it won't block trying
  296.      to do the ioctl()'s below.  Checking gdb_has_a_terminal
  297.      avoids attempting all the ioctl's when running in batch.  */
  298.   if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal () == 0)
  299.     return;
  300.  
  301.   if (!terminal_is_ours)
  302.     {
  303.       /* Ignore this signal since it will happen when we try to set the
  304.      pgrp.  */
  305.       void (*osigttou) ();
  306.       int result;
  307.  
  308.       terminal_is_ours = 1;
  309.  
  310. #ifdef SIGTTOU
  311.       if (job_control)
  312.     osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN);
  313. #endif
  314.  
  315.       if (inferior_ttystate)
  316.     free (inferior_ttystate);
  317.       inferior_ttystate = SERIAL_GET_TTY_STATE (stdin_serial);
  318. #ifdef HAVE_TERMIOS
  319.       inferior_process_group = tcgetpgrp (0);
  320. #endif
  321. #ifdef HAVE_SGTTY
  322.       ioctl (0, TIOCGPGRP, &inferior_process_group);
  323. #endif
  324.  
  325.       /* Here we used to set ICANON in our ttystate, but I believe this
  326.      was an artifact from before when we used readline.  Readline sets
  327.      the tty state when it needs to.  */
  328.  
  329.       /* Set tty state to our_ttystate.  We don't change in our out of raw
  330.      mode, to avoid flushing input.  We need to do the same thing
  331.      regardless of output_only, because we don't have separate
  332.      terminal_is_ours and terminal_is_ours_for_output flags.  It's OK,
  333.      though, since readline will deal with raw mode when/if it needs to.
  334.      */
  335.       SERIAL_NOFLUSH_SET_TTY_STATE (stdin_serial, our_ttystate,
  336.                     inferior_ttystate);
  337.  
  338.       if (job_control)
  339.     {
  340. #ifdef HAVE_TERMIOS
  341.       result = tcsetpgrp (0, our_process_group);
  342. #if 0
  343.       /* This fails on Ultrix with EINVAL if you run the testsuite
  344.          in the background with nohup, and then log out.  GDB never
  345.          used to check for an error here, so perhaps there are other
  346.          such situations as well.  */
  347.       if (result == -1)
  348.         fprintf_unfiltered (gdb_stderr, "[tcsetpgrp failed in terminal_ours: %s]\n",
  349.              strerror (errno));
  350. #endif
  351. #endif /* termios */
  352.  
  353. #ifdef HAVE_SGTTY
  354.       result = ioctl (0, TIOCSPGRP, &our_process_group);
  355. #endif
  356.     }
  357.  
  358. #ifdef SIGTTOU
  359.       if (job_control)
  360.     signal (SIGTTOU, osigttou);
  361. #endif
  362.  
  363.       if (!job_control)
  364.     {
  365.       signal (SIGINT, sigint_ours);
  366.       signal (SIGQUIT, sigquit_ours);
  367.     }
  368.  
  369. #ifdef F_GETFL
  370.       tflags_inferior = fcntl (0, F_GETFL, 0);
  371.  
  372.       /* Is there a reason this is being done twice?  It happens both
  373.      places we use F_SETFL, so I'm inclined to think perhaps there
  374.      is some reason, however perverse.  Perhaps not though...  */
  375.       result = fcntl (0, F_SETFL, tflags_ours);
  376.       result = fcntl (0, F_SETFL, tflags_ours);
  377. #endif
  378.  
  379.       result = result;    /* lint */
  380.     }
  381. }
  382.  
  383. /* ARGSUSED */
  384. void
  385. term_info (arg, from_tty)
  386.      char *arg;
  387.      int from_tty;
  388. {
  389.   target_terminal_info (arg, from_tty);
  390. }
  391.  
  392. /* ARGSUSED */
  393. void
  394. child_terminal_info (args, from_tty)
  395.      char *args;
  396.      int from_tty;
  397. {
  398.   if (!gdb_has_a_terminal ())
  399.     {
  400.       printf_filtered ("This GDB does not control a terminal.\n");
  401.       return;
  402.     }
  403.  
  404.   printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
  405.  
  406.   /* First the fcntl flags.  */
  407.   {
  408.     int flags;
  409.     
  410.     flags = tflags_inferior;
  411.  
  412.     printf_filtered ("File descriptor flags = ");
  413.  
  414. #ifndef O_ACCMODE
  415. #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
  416. #endif
  417.     /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
  418.     switch (flags & (O_ACCMODE))
  419.       {
  420.       case O_RDONLY: printf_filtered ("O_RDONLY"); break;
  421.       case O_WRONLY: printf_filtered ("O_WRONLY"); break;
  422.       case O_RDWR: printf_filtered ("O_RDWR"); break;
  423.       }
  424.     flags &= ~(O_ACCMODE);
  425.  
  426. #ifdef O_NONBLOCK
  427.     if (flags & O_NONBLOCK) 
  428.       printf_filtered (" | O_NONBLOCK");
  429.     flags &= ~O_NONBLOCK;
  430. #endif
  431.     
  432. #if defined (O_NDELAY)
  433.     /* If O_NDELAY and O_NONBLOCK are defined to the same thing, we will
  434.        print it as O_NONBLOCK, which is good cause that is what POSIX
  435.        has, and the flag will already be cleared by the time we get here.  */
  436.     if (flags & O_NDELAY)
  437.       printf_filtered (" | O_NDELAY");
  438.     flags &= ~O_NDELAY;
  439. #endif
  440.  
  441.     if (flags & O_APPEND)
  442.       printf_filtered (" | O_APPEND");
  443.     flags &= ~O_APPEND;
  444.  
  445. #if defined (O_BINARY)
  446.     if (flags & O_BINARY)
  447.       printf_filtered (" | O_BINARY");
  448.     flags &= ~O_BINARY;
  449. #endif
  450.  
  451.     if (flags)
  452.       printf_filtered (" | 0x%x", flags);
  453.     printf_filtered ("\n");
  454.   }
  455.  
  456. #ifdef PROCESS_GROUP_TYPE
  457.   printf_filtered ("Process group = %d\n", inferior_process_group);
  458. #endif
  459.  
  460.   SERIAL_PRINT_TTY_STATE (stdin_serial, inferior_ttystate);
  461. }
  462.  
  463. /* NEW_TTY_PREFORK is called before forking a new child process,
  464.    so we can record the state of ttys in the child to be formed.
  465.    TTYNAME is null if we are to share the terminal with gdb;
  466.    or points to a string containing the name of the desired tty.
  467.  
  468.    NEW_TTY is called in new child processes under Unix, which will
  469.    become debugger target processes.  This actually switches to
  470.    the terminal specified in the NEW_TTY_PREFORK call.  */
  471.  
  472. void
  473. new_tty_prefork (ttyname)
  474.      char *ttyname;
  475. {
  476.   /* Save the name for later, for determining whether we and the child
  477.      are sharing a tty.  */
  478.   inferior_thisrun_terminal = ttyname;
  479. }
  480.  
  481. void
  482. new_tty ()
  483. {
  484.   register int tty;
  485.  
  486.   if (inferior_thisrun_terminal == 0)
  487.     return;
  488. #if !defined(__GO32__)
  489. #ifdef TIOCNOTTY
  490.   /* Disconnect the child process from our controlling terminal.  On some
  491.      systems (SVR4 for example), this may cause a SIGTTOU, so temporarily
  492.      ignore SIGTTOU. */
  493.   tty = open("/dev/tty", O_RDWR);
  494.   if (tty > 0)
  495.     {
  496.       void (*osigttou) ();
  497.  
  498.       osigttou = (void (*)()) signal(SIGTTOU, SIG_IGN);
  499.       ioctl(tty, TIOCNOTTY, 0);
  500.       close(tty);
  501.       signal(SIGTTOU, osigttou);
  502.     }
  503. #endif
  504.  
  505.   /* Now open the specified new terminal.  */
  506.  
  507. #ifdef USE_O_NOCTTY
  508.   tty = open(inferior_thisrun_terminal, O_RDWR | O_NOCTTY);
  509. #else
  510.   tty = open(inferior_thisrun_terminal, O_RDWR);
  511. #endif
  512.   if (tty == -1)
  513.     {
  514.       print_sys_errmsg (inferior_thisrun_terminal, errno);
  515.       _exit(1);
  516.     }
  517.  
  518.   /* Avoid use of dup2; doesn't exist on all systems.  */
  519.   if (tty != 0)
  520.     { close (0); dup (tty); }
  521.   if (tty != 1)
  522.     { close (1); dup (tty); }
  523.   if (tty != 2)
  524.     { close (2); dup (tty); }
  525.   if (tty > 2)
  526.     close(tty);
  527. #endif /* !go32 */
  528. }
  529.  
  530. /* Kill the inferior process.  Make us have no inferior.  */
  531.  
  532. /* ARGSUSED */
  533. static void
  534. kill_command (arg, from_tty)
  535.      char *arg;
  536.      int from_tty;
  537. {
  538.   /* Shouldn't this be target_has_execution?  FIXME.  */
  539.   if (inferior_pid == 0)
  540.     error ("The program is not being run.");
  541.   if (!query ("Kill the program being debugged? "))
  542.     error ("Not confirmed.");
  543.   target_kill ();
  544.  
  545.   init_thread_list();        /* Destroy thread info */
  546.  
  547.   /* Killing off the inferior can leave us with a core file.  If so,
  548.      print the state we are left in.  */
  549.   if (target_has_stack) {
  550.     printf_filtered ("In %s,\n", current_target->to_longname);
  551.     if (selected_frame == NULL)
  552.       fputs_filtered ("No selected stack frame.\n", gdb_stdout);
  553.     else
  554.       print_stack_frame (selected_frame, selected_frame_level, 1);
  555.   }
  556. }
  557.  
  558. /* The inferior process has died.  Long live the inferior!  */
  559.  
  560. void
  561. generic_mourn_inferior ()
  562. {
  563.   inferior_pid = 0;
  564.   attach_flag = 0;
  565.   breakpoint_init_inferior ();
  566.   registers_changed ();
  567.  
  568. #ifdef CLEAR_DEFERRED_STORES
  569.   /* Delete any pending stores to the inferior... */
  570.   CLEAR_DEFERRED_STORES;
  571. #endif
  572.  
  573.   reopen_exec_file ();
  574.   reinit_frame_cache ();
  575.  
  576.   /* It is confusing to the user for ignore counts to stick around
  577.      from previous runs of the inferior.  So clear them.  */
  578.   breakpoint_clear_ignore_counts ();
  579. }
  580.  
  581. /* Call set_sigint_trap when you need to pass a signal on to an attached
  582.    process when handling SIGINT */
  583.  
  584. /* ARGSUSED */
  585. static void
  586. pass_signal (signo)
  587.     int signo;
  588. {
  589.   kill (inferior_pid, SIGINT);
  590. }
  591.  
  592. static void (*osig)();
  593.  
  594. void
  595. set_sigint_trap()
  596. {
  597.   osig = (void (*) ()) signal (SIGINT, pass_signal);
  598. }
  599.  
  600. void
  601. clear_sigint_trap()
  602. {
  603.   signal (SIGINT, osig);
  604. }
  605.  
  606.  
  607. int job_control;
  608.  
  609. /* This is here because this is where we figure out whether we (probably)
  610.    have job control.  Just using job_control only does part of it because
  611.    setpgid or setpgrp might not exist on a system without job control.
  612.    It might be considered misplaced (on the other hand, process groups and
  613.    job control are closely related to ttys).
  614.  
  615.    For a more clean implementation, in libiberty, put a setpgid which merely
  616.    calls setpgrp and a setpgrp which does nothing (any system with job control
  617.    will have one or the other).  */
  618. int
  619. gdb_setpgid ()
  620. {
  621.   int retval = 0;
  622.   if (job_control)
  623.     {
  624. #if defined (NEED_POSIX_SETPGID) || defined (HAVE_TERMIOS)
  625.       /* Do all systems with termios have setpgid?  I hope so.  */
  626.       /* setpgid (0, 0) is supposed to work and mean the same thing as
  627.      this, but on Ultrix 4.2A it fails with EPERM (and
  628.      setpgid (getpid (), getpid ()) succeeds).  */
  629.       retval = setpgid (getpid (), getpid ());
  630. #else
  631. #if defined (TIOCGPGRP)
  632. #if defined(USG) && !defined(SETPGRP_ARGS)
  633.       retval = setpgrp ();
  634. #else
  635.       retval = setpgrp (getpid (), getpid ());
  636. #endif /* USG */
  637. #endif /* TIOCGPGRP.  */
  638. #endif /* NEED_POSIX_SETPGID */
  639.     }
  640.   return retval;
  641. }
  642.  
  643. void
  644. _initialize_inflow ()
  645. {
  646.   add_info ("terminal", term_info,
  647.        "Print inferior's saved terminal status.");
  648.  
  649.   add_com ("kill", class_run, kill_command,
  650.        "Kill execution of program being debugged.");
  651.  
  652.   inferior_pid = 0;
  653.  
  654.   terminal_is_ours = 1;
  655.  
  656.   /* OK, figure out whether we have job control.  If neither termios nor
  657.      sgtty (i.e. termio or go32), leave job_control 0.  */
  658.  
  659. #if defined (HAVE_TERMIOS)
  660.   /* Do all systems with termios have the POSIX way of identifying job
  661.      control?  I hope so.  */
  662. #ifdef _POSIX_JOB_CONTROL
  663.   job_control = 1;
  664. #else
  665.   job_control = sysconf (_SC_JOB_CONTROL);
  666. #endif
  667. #endif /* termios */
  668.  
  669. #ifdef HAVE_SGTTY
  670. #ifdef TIOCGPGRP
  671.   job_control = 1;
  672. #else
  673.   job_control = 0;
  674. #endif /* TIOCGPGRP */
  675. #endif /* sgtty */
  676. }
  677.